diff --git a/bin/app/data/src/test2/header.h b/bin/app/data/src/test2/header.h index 65d3600b..57396acb 100644 --- a/bin/app/data/src/test2/header.h +++ b/bin/app/data/src/test2/header.h @@ -1,16 +1,10 @@ -template +template class TemplateTestClass { + void run(T param); }; -template -class TemplateTestClass +template +void TemplateTestClass::run(T param) { - int foo; -}; - -template<> -class TemplateTestClass -{ - int foo; -}; \ No newline at end of file +} \ No newline at end of file diff --git a/bin/app/data/src/test2/main.cpp b/bin/app/data/src/test2/main.cpp index f5129aef..a5eb0926 100644 --- a/bin/app/data/src/test2/main.cpp +++ b/bin/app/data/src/test2/main.cpp @@ -2,7 +2,6 @@ int main() { - TemplateTestClass t2; -// TemplateTestClass t3; + TemplateTestClass t2; return 0; } \ No newline at end of file diff --git a/bin/test/data/log/test_log.txt b/bin/test/data/log/test_log.txt index 99700d16..66447c43 100644 --- a/bin/test/data/log/test_log.txt +++ b/bin/test/data/log/test_log.txt @@ -1,26 +1,4 @@ ConfigManager.cpp ERROR: value path/to/nowhere is not present in config. -Token.cpp ERROR: Location Id was not referenced by this Token. -Node.cpp WARNING: Cannot change NodeType after it was already set from namespace to class -Edge.cpp ERROR: Nodes are not plain copies. -Edge.cpp ERROR: Edge usage can't go from Node undefined to Node undefined -Edge.cpp ERROR: Edge usage can't go from Node undefined to Node undefined -Edge.cpp ERROR: Edge usage can't go from Node undefined to Node undefined -Storage.cpp INFO: class: A -Storage.cpp INFO: method: A::A -Storage.cpp INFO: global usage: A::A -> A::count -Storage.cpp INFO: method: A::getCount -Storage.cpp INFO: global usage: A::getCount -> A::count -Storage.cpp INFO: method: A::process -Storage.cpp INFO: field: A::count -Storage.cpp INFO: class: B -Storage.cpp INFO: inheritance: B : A -Storage.cpp INFO: method: B::process -Storage.cpp INFO: override: A::process -> B::process < 0:0 0:0> -Storage.cpp INFO: type usage: B::process -> int -Storage.cpp INFO: function: main -Storage.cpp INFO: type usage: main -> B -Storage.cpp INFO: call: main -> B::B -Storage.cpp INFO: call: main -> A::getCount Storage.cpp INFO: class: A Storage.cpp INFO: method: A::A Storage.cpp INFO: global usage: A::A -> A::count @@ -54,6 +32,28 @@ SearchMatch.cpp INFO: 237 A::A ^^^^ +Storage.cpp INFO: class: A +Storage.cpp INFO: method: A::A +Storage.cpp INFO: global usage: A::A -> A::count +Storage.cpp INFO: method: A::getCount +Storage.cpp INFO: global usage: A::getCount -> A::count +Storage.cpp INFO: method: A::process +Storage.cpp INFO: field: A::count +Storage.cpp INFO: class: B +Storage.cpp INFO: inheritance: B : A +Storage.cpp INFO: method: B::process +Storage.cpp INFO: override: A::process -> B::process < 0:0 0:0> +Storage.cpp INFO: type usage: B::process -> int +Storage.cpp INFO: function: main +Storage.cpp INFO: type usage: main -> B +Storage.cpp INFO: call: main -> B::B +Storage.cpp INFO: call: main -> A::getCount +Token.cpp ERROR: Location Id was not referenced by this Token. +Node.cpp WARNING: Cannot change NodeType after it was already set from namespace to class +Edge.cpp ERROR: Nodes are not plain copies. +Edge.cpp ERROR: Edge usage can't go from Node undefined to Node undefined +Edge.cpp ERROR: Edge usage can't go from Node undefined to Node undefined +Edge.cpp ERROR: Edge usage can't go from Node undefined to Node undefined Settings.cpp WARNING: File for Settings not found. ConfigManager.cpp ERROR: value Bool is not present in config. ConfigManager.cpp ERROR: value Int is not present in config. @@ -69,6 +69,7 @@ ConfigManager.cpp ERROR: value Int is not present in config. ConfigManager.cpp ERROR: value Float is not present in config. ConfigManager.cpp ERROR: value String is not present in config. ConfigManager.cpp ERROR: value NewBool is not present in config. +Graph.cpp ERROR: Can't remove member edge, without removing the child node. Storage.cpp INFO: typedef: type -> int Storage.cpp INFO: class: Class Storage.cpp INFO: struct: Struct @@ -124,7 +125,6 @@ Storage.cpp INFO: call: main -> isTrue Storage.cpp INFO: function: isTrue Storage.cpp INFO: function: main Storage.cpp INFO: call: main -> isTrue -Graph.cpp ERROR: Can't remove member edge, without removing the child node. TextAccess.cpp WARNING: Index 'firstLine' has to be lower or equal index 'lastLine', is 3 > 2 TextAccess.cpp WARNING: Tried to access index 10. Maximum index is 8 TextAccess.cpp WARNING: Tried to access index 10. Maximum index is 8 diff --git a/src/lib/data/parser/cxx/ASTVisitor.cpp b/src/lib/data/parser/cxx/ASTVisitor.cpp index 35b91700..26a6a363 100644 --- a/src/lib/data/parser/cxx/ASTVisitor.cpp +++ b/src/lib/data/parser/cxx/ASTVisitor.cpp @@ -494,12 +494,19 @@ void ASTVisitor::VisitCXXConstructExprInDeclBody(clang::FunctionDecl* decl, clan if (parentStmt && parentStmt->getStmtClass() == clang::Stmt::DeclStmtClass) { clang::DeclStmt* declStmt = clang::dyn_cast(parentStmt); - clang::Decl* decl = declStmt->getSingleDecl(); - if (clang::isa(decl)) + if (declStmt->isSingleDecl()) { - clang::NamedDecl* namedDecl = clang::dyn_cast(decl); - int variableNameLength = namedDecl->getName().size(); - endLocationOffset = variableNameLength - 1; + clang::Decl* decl = declStmt->getSingleDecl(); + if (clang::isa(decl)) + { + clang::NamedDecl* namedDecl = clang::dyn_cast(decl); + int variableNameLength = namedDecl->getName().size(); + endLocationOffset = variableNameLength - 1; + } + } + else + { + // TODO: maybe we should handle this case... it occurs when parsing a for-each loop } } } diff --git a/src/lib/data/parser/cxx/utilityCxx.cpp b/src/lib/data/parser/cxx/utilityCxx.cpp index b7d7d43e..3a6710a0 100644 --- a/src/lib/data/parser/cxx/utilityCxx.cpp +++ b/src/lib/data/parser/cxx/utilityCxx.cpp @@ -21,83 +21,130 @@ namespace utility DataTypeQualifierList qualifierList; DataTypeModifierStack modifierStack; - while (true) + bool needsRefinement = true; + + while (needsRefinement) { const clang::Type* type = qualType.getTypePtr(); - if (type->getAs()) + clang::Type::TypeClass tk = type->getTypeClass(); + switch (type->getTypeClass()) { - typeNameHerarchy.push_back(utility::substrAfter(qualType.getAsString(), ' ')); - break; - } - else if (type->isPointerType()) - { - std::shared_ptr modifier = std::make_shared(); - if (qualType.isConstQualified()) + case clang::Type::Paren: { - modifier->addQualifier(DataTypeQualifierList::QUALIFIER_CONST); + qualType = type->getAs()->getInnerType(); + // what about qualifiers and modifiers + break; } - modifierStack.push(modifier); - - qualType = type->getPointeeType(); - } - else if (type->isArrayType()) - { - std::shared_ptr modifier = std::make_shared(); - if (qualType.isConstQualified()) + case clang::Type::Typedef: { - modifier->addQualifier(DataTypeQualifierList::QUALIFIER_CONST); + typeNameHerarchy = getDeclNameHierarchy(type->getAs()->getDecl()); + needsRefinement = false; + break; } - modifierStack.push(modifier); + case clang::Type::Pointer: + { + std::shared_ptr modifier = std::make_shared(); + if (qualType.isConstQualified()) + { + modifier->addQualifier(DataTypeQualifierList::QUALIFIER_CONST); + } + modifierStack.push(modifier); - qualType = clang::dyn_cast(type)->getElementType(); - } - else if (type->isReferenceType()) - { - std::shared_ptr modifier = std::make_shared(); - // references can not be const qualified - modifierStack.push(modifier); + qualType = type->getPointeeType(); + break; + } + case clang::Type::ConstantArray: + case clang::Type::VariableArray: + case clang::Type::DependentSizedArray: + case clang::Type::IncompleteArray: + { + std::shared_ptr modifier = std::make_shared(); + if (qualType.isConstQualified()) + { + modifier->addQualifier(DataTypeQualifierList::QUALIFIER_CONST); + } + modifierStack.push(modifier); - qualType = type->getPointeeType(); - } - else - { - const clang::Type* type = qualType.getUnqualifiedType().getTypePtr(); + qualType = clang::dyn_cast(type)->getElementType(); + break; + } + case clang::Type::LValueReference: + case clang::Type::RValueReference: + { + std::shared_ptr modifier = std::make_shared(); + // references can not be const qualified + modifierStack.push(modifier); - if (clang::isa(type)) // get the real type here + qualType = type->getPointeeType(); + break; + } + case clang::Type::Elaborated: { const clang::ElaboratedType* et = clang::dyn_cast(type); - type = et->getNamedType().getUnqualifiedType().getTypePtr(); + qualType = et->getNamedType(); + break; } - - if (clang::isa(type)) + case clang::Type::Enum: + case clang::Type::Record: { - typeNameHerarchy = getDeclNameHierarchy(clang::dyn_cast(type)->getDecl()); + typeNameHerarchy = getDeclNameHierarchy(type->getAs()->getDecl()); + needsRefinement = false; + break; } - else + case clang::Type::Builtin: + case clang::Type::TemplateSpecialization: + { + clang::PrintingPolicy pp = clang::PrintingPolicy(clang::LangOptions()); + pp.SuppressTagKeyword = true; // value "true": for a class A it prints "A" instead of "class A" + pp.Bool = true; // value "true": prints bool type as "bool" instead of "_Bool" + std::string typeName = qualType.getUnqualifiedType().getAsString(pp); + typeNameHerarchy.push_back(typeName); + + needsRefinement = false; + break; + } + case clang::Type::TemplateTypeParm: { clang::PrintingPolicy pp = clang::PrintingPolicy(clang::LangOptions()); pp.SuppressTagKeyword = true; // value "true": for a class A it prints "A" instead of "class A" pp.Bool = true; // value "true": prints bool type as "bool" instead of "_Bool" std::string typeName = qualType.getUnqualifiedType().getAsString(pp); - if (type->isTemplateTypeParmType()) + clang::TemplateTypeParmDecl* templateTypeParmDecl = clang::dyn_cast(qualType)->getDecl(); + typeNameHerarchy = getContextNameHierarchy(templateTypeParmDecl->getDeclContext()); + if (typeNameHerarchy.size() == 0) { - clang::TemplateTypeParmDecl* templateTypeParmDecl = clang::dyn_cast(qualType.getUnqualifiedType())->getDecl(); - if (templateTypeParmDecl) - { - typeNameHerarchy = getContextNameHierarchy(templateTypeParmDecl->getDeclContext()); - typeNameHerarchy.back() += "::" + typeName; - } + int gogo = 0; + typeNameHerarchy.push_back(typeName); // HOT: fix this one! definition of template function outside of class scope! } else { - typeNameHerarchy.push_back(typeName); + typeNameHerarchy.back() += "::" + typeName; } + needsRefinement = false; + break; + } + case clang::Type::SubstTemplateTypeParm: + { + const clang::SubstTemplateTypeParmType* substType = type->getAs(); + qualType = substType->getReplacementType(); + break; + } + default: + { + LOG_ERROR(std::string("Unhandled kind of type encountered: ") + type->getTypeClassName()); + clang::PrintingPolicy pp = clang::PrintingPolicy(clang::LangOptions()); + pp.SuppressTagKeyword = true; // value "true": for a class A it prints "A" instead of "class A" + pp.Bool = true; // value "true": prints bool type as "bool" instead of "_Bool" + std::string typeName = qualType.getUnqualifiedType().getAsString(pp); + + typeNameHerarchy.push_back(typeName); + + needsRefinement = false; + break; } - break; } } - if (qualType.isConstQualified()) { qualifierList.addQualifier(DataTypeQualifierList::QUALIFIER_CONST);