Scope = "";
}
+ auto Add = [&](llvm::StringRef Scope, llvm::StringRef Name,
+ bool Underscores) {
+ CodeCompletionBuilder Builder(Results.getAllocator(),
+ Results.getCodeCompletionTUInfo());
+ llvm::SmallString<32> Text;
+ if (!Scope.empty()) {
+ Text.append(Scope);
+ Text.append("::");
+ }
+ if (Underscores)
+ Text.append("__");
+ Text.append(Name);
+ if (Underscores)
+ Text.append("__");
+ Builder.AddTypedTextChunk(Results.getAllocator().CopyString(Text));
+
+ if (!A.ArgNames.empty()) {
+ Builder.AddChunk(CodeCompletionString::CK_LeftParen, "(");
+ bool First = true;
+ for (const char *Arg : A.ArgNames) {
+ if (!First)
+ Builder.AddChunk(CodeCompletionString::CK_Comma, ", ");
+ First = false;
+ Builder.AddPlaceholderChunk(Arg);
+ }
+ Builder.AddChunk(CodeCompletionString::CK_RightParen, ")");
+ }
+
+ Results.AddResult(Builder.TakeString());
+ };
+
// Generate the non-underscore-guarded result.
// Note this is (a suffix of) the NormalizedFullName, no need to copy.
// If an underscore-guarded scope was specified, only the
// underscore-guarded attribute name is relevant.
if (!InScopeUnderscore)
- Results.AddResult(Scope.empty() ? Name.data() : S.NormalizedFullName);
+ Add(Scope, Name, /*Underscores=*/false);
// Generate the underscore-guarded version, for syntaxes that support it.
// We skip this if the scope was already spelled and not guarded, or
// we must spell it and can't guard it.
if (!(InScope && !InScopeUnderscore) && SyntaxSupportsGuards) {
llvm::SmallString<32> Guarded;
- if (!Scope.empty()) {
+ if (Scope.empty()) {
+ Add(Scope, Name, /*Underscores=*/true);
+ } else {
const char *GuardedScope = underscoreAttrScope(Scope);
if (!GuardedScope)
continue;
- Guarded.append(GuardedScope);
- Guarded.append("::");
+ Add(GuardedScope, Name, /*Underscores=*/true);
}
- Guarded.append("__");
- Guarded.append(Name);
- Guarded.append("__");
- Results.AddResult(
- CodeCompletionResult(Results.getAllocator().CopyString(Guarded)));
}
- // FIXME: include the list of arg names (not currently exposed).
// It may be nice to include the Kind so we can look up the docs later.
}
};
int a [[gnu::used]];
// RUN: %clang_cc1 -code-completion-at=%s:1:9 %s | FileCheck --check-prefix=STD %s
-// STD: COMPLETION: __carries_dependency__
-// STD-NOT: COMPLETION: __convergent__
-// STD: COMPLETION: __gnu__::__used__
-// STD-NOT: COMPLETION: __gnu__::used
-// STD-NOT: COMPLETION: __used__
-// STD: COMPLETION: _Clang::__convergent__
-// STD: COMPLETION: carries_dependency
-// STD-NOT: COMPLETION: clang::called_once
-// STD: COMPLETION: clang::convergent
-// STD-NOT: COMPLETION: convergent
-// STD-NOT: COMPLETION: gnu::__used__
-// STD: COMPLETION: gnu::used
-// STD-NOT: COMPLETION: used
+// STD: COMPLETION: Pattern : __carries_dependency__
+// STD-NOT: COMPLETION: Pattern : __convergent__
+// STD: COMPLETION: Pattern : __gnu__::__used__
+// STD-NOT: COMPLETION: Pattern : __gnu__::used
+// STD-NOT: COMPLETION: Pattern : __used__
+// STD: COMPLETION: Pattern : _Clang::__convergent__
+// STD: COMPLETION: Pattern : carries_dependency
+// STD-NOT: COMPLETION: Pattern : clang::called_once
+// STD: COMPLETION: Pattern : clang::convergent
+// STD-NOT: COMPLETION: Pattern : convergent
+// STD-NOT: COMPLETION: Pattern : gnu::__used__
+// STD: COMPLETION: Pattern : gnu::abi_tag(<#Tags...#>)
+// STD: COMPLETION: Pattern : gnu::alias(<#Aliasee#>)
+// STD: COMPLETION: Pattern : gnu::used
+// STD-NOT: COMPLETION: Pattern : used
// RUN: %clang_cc1 -code-completion-at=%s:1:9 -xobjective-c++ %s | FileCheck --check-prefix=STD-OBJC %s
-// STD-OBJC: COMPLETION: clang::called_once
+// STD-OBJC: COMPLETION: Pattern : clang::called_once
// RUN: %clang_cc1 -code-completion-at=%s:1:14 %s | FileCheck --check-prefix=STD-NS %s
-// STD-NS-NOT: COMPLETION: __used__
-// STD-NS-NOT: COMPLETION: carries_dependency
-// STD-NS-NOT: COMPLETION: clang::convergent
-// STD-NS-NOT: COMPLETION: convergent
-// STD-NS-NOT: COMPLETION: gnu::used
-// STD-NS: COMPLETION: used
+// STD-NS-NOT: COMPLETION: Pattern : __used__
+// STD-NS-NOT: COMPLETION: Pattern : carries_dependency
+// STD-NS-NOT: COMPLETION: Pattern : clang::convergent
+// STD-NS-NOT: COMPLETION: Pattern : convergent
+// STD-NS-NOT: COMPLETION: Pattern : gnu::used
+// STD-NS: COMPLETION: Pattern : used
int b [[__gnu__::used]];
-// RUN: %clang_cc1 -code-completion-at=%s:25:18 %s | FileCheck --check-prefix=STD-NSU %s
-// STD-NSU: COMPLETION: __used__
-// STD-NSU-NOT: COMPLETION: used
+// RUN: %clang_cc1 -code-completion-at=%s:27:18 %s | FileCheck --check-prefix=STD-NSU %s
+// STD-NSU: COMPLETION: Pattern : __used__
+// STD-NSU-NOT: COMPLETION: Pattern : used
int c [[using gnu: used]];
-// RUN: %clang_cc1 -code-completion-at=%s:30:15 %s | FileCheck --check-prefix=STD-USING %s
+// RUN: %clang_cc1 -code-completion-at=%s:32:15 %s | FileCheck --check-prefix=STD-USING %s
// STD-USING: COMPLETION: __gnu__
// STD-USING: COMPLETION: _Clang
-// STD-USING-NOT: COMPLETION: carries_dependency
+// STD-USING-NOT: COMPLETION: Pattern : carries_dependency
// STD-USING: COMPLETION: clang
-// STD-USING-NOT: COMPLETION: clang::
-// STD-USING-NOT: COMPLETION: gnu::
+// STD-USING-NOT: COMPLETION: Pattern : clang::
+// STD-USING-NOT: COMPLETION: Pattern : gnu::
// STD-USING: COMPLETION: gnu
-// RUN: %clang_cc1 -code-completion-at=%s:30:20 %s | FileCheck --check-prefix=STD-NS %s
+// RUN: %clang_cc1 -code-completion-at=%s:32:20 %s | FileCheck --check-prefix=STD-NS %s
int d __attribute__((used));
-// RUN: %clang_cc1 -code-completion-at=%s:41:22 %s | FileCheck --check-prefix=GNU %s
-// GNU: COMPLETION: __carries_dependency__
-// GNU: COMPLETION: __convergent__
-// GNU-NOT: COMPLETION: __gnu__::__used__
-// GNU: COMPLETION: __used__
-// GNU-NOT: COMPLETION: _Clang::__convergent__
-// GNU: COMPLETION: carries_dependency
-// GNU-NOT: COMPLETION: clang::convergent
-// GNU: COMPLETION: convergent
-// GNU-NOT: COMPLETION: gnu::used
-// GNU: COMPLETION: used
+// RUN: %clang_cc1 -code-completion-at=%s:43:22 %s | FileCheck --check-prefix=GNU %s
+// GNU: COMPLETION: Pattern : __carries_dependency__
+// GNU: COMPLETION: Pattern : __convergent__
+// GNU-NOT: COMPLETION: Pattern : __gnu__::__used__
+// GNU: COMPLETION: Pattern : __used__
+// GNU-NOT: COMPLETION: Pattern : _Clang::__convergent__
+// GNU: COMPLETION: Pattern : carries_dependency
+// GNU-NOT: COMPLETION: Pattern : clang::convergent
+// GNU: COMPLETION: Pattern : convergent
+// GNU-NOT: COMPLETION: Pattern : gnu::used
+// GNU: COMPLETION: Pattern : used
#pragma clang attribute push (__attribute__((internal_linkage)), apply_to=variable)
int e;
#pragma clang attribute pop
-// RUN: %clang_cc1 -code-completion-at=%s:54:46 %s | FileCheck --check-prefix=PRAGMA %s
-// PRAGMA: internal_linkage
+// RUN: %clang_cc1 -code-completion-at=%s:56:46 %s | FileCheck --check-prefix=PRAGMA %s
+// PRAGMA: COMPLETION: Pattern : internal_linkage
#ifdef MS_EXT
int __declspec(thread) f;
-// RUN: %clang_cc1 -fms-extensions -DMS_EXT -code-completion-at=%s:61:16 %s | FileCheck --check-prefix=DS %s
-// DS-NOT: COMPLETION: __convergent__
-// DS-NOT: COMPLETION: __used__
-// DS-NOT: COMPLETION: clang::convergent
-// DS-NOT: COMPLETION: convergent
-// DS: COMPLETION: thread
-// DS-NOT: COMPLETION: used
-// DS: COMPLETION: uuid
+// RUN: %clang_cc1 -fms-extensions -DMS_EXT -code-completion-at=%s:63:16 %s | FileCheck --check-prefix=DS %s
+// DS-NOT: COMPLETION: Pattern : __convergent__
+// DS-NOT: COMPLETION: Pattern : __used__
+// DS-NOT: COMPLETION: Pattern : clang::convergent
+// DS-NOT: COMPLETION: Pattern : convergent
+// DS: COMPLETION: Pattern : thread
+// DS-NOT: COMPLETION: Pattern : used
+// DS: COMPLETION: Pattern : uuid
[uuid("123e4567-e89b-12d3-a456-426614174000")] struct g;
-// RUN: %clang_cc1 -fms-extensions -DMS_EXT -code-completion-at=%s:71:2 %s | FileCheck --check-prefix=MS %s
-// MS-NOT: COMPLETION: __uuid__
-// MS-NOT: COMPLETION: clang::convergent
-// MS-NOT: COMPLETION: convergent
-// MS-NOT: COMPLETION: thread
-// MS-NOT: COMPLETION: used
-// MS: COMPLETION: uuid
+// RUN: %clang_cc1 -fms-extensions -DMS_EXT -code-completion-at=%s:73:2 %s | FileCheck --check-prefix=MS %s
+// MS-NOT: COMPLETION: Pattern : __uuid__
+// MS-NOT: COMPLETION: Pattern : clang::convergent
+// MS-NOT: COMPLETION: Pattern : convergent
+// MS-NOT: COMPLETION: Pattern : thread
+// MS-NOT: COMPLETION: Pattern : used
+// MS: COMPLETION: Pattern : uuid
#endif // MS_EXT
void foo() {
{}
}
// FIXME: support for omp attributes would be nice.
-// RUN: %clang_cc1 -fopenmp -code-completion-at=%s:82:5 %s | FileCheck --check-prefix=OMP-NS --allow-empty %s
-// OMP-NS-NOT: omp
-// RUN: %clang_cc1 -fopenmp -code-completion-at=%s:82:10 %s | FileCheck --check-prefix=OMP-ATTR --allow-empty %s
-// OMP-ATTR-NOT: sequence
-// RUN: %clang_cc1 -fopenmp -code-completion-at=%s:82:19 %s | FileCheck --check-prefix=OMP-NESTED --allow-empty %s
-// OMP-NESTED-NOT: directive
+// RUN: %clang_cc1 -fopenmp -code-completion-at=%s:84:5 %s | FileCheck --check-prefix=OMP-NS --allow-empty %s
+// OMP-NS-NOT: COMPLETION: omp
+// RUN: %clang_cc1 -fopenmp -code-completion-at=%s:84:10 %s | FileCheck --check-prefix=OMP-ATTR --allow-empty %s
+// OMP-ATTR-NOT: COMPLETION: Pattern : sequence
+// RUN: %clang_cc1 -fopenmp -code-completion-at=%s:84:19 %s | FileCheck --check-prefix=OMP-NESTED --allow-empty %s
+// OMP-NESTED-NOT: COMPLETION: Pattern : directive